package com.ease.map.handler.feature.draw {
    import com.ease.map.Map;
    import com.ease.map.common.enum.HandlerEnum;
    import com.ease.map.common.enum.MapActionEnum;
    import com.ease.map.events.DrawEvent;
    import com.ease.map.events.MapEvent;
    import com.ease.map.feature.Feature;
    import com.ease.map.geometry.PointGeometry;
    import com.ease.map.geometry.PolylineGeometry;
    import com.ease.map.geometry.basetype.Location;
    import com.ease.map.geometry.basetype.Pixel;
    import com.ease.map.handler.mouse.ClickHandler;
    import com.ease.map.style.IStyle;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.ui.Keyboard;
    import com.ease.map.handler.feature.draw.AbstractDrawHandler;

    [ExcludeClass]
    public class DrawLineHandler extends AbstractDrawHandler {
        /**
         * Single id of the path
         */
        private var _id:Number = 0;

        private var polyline:PolylineGeometry = null;

        /**
         * The LineStringfeature currently drawn
         * */
        private var feature:Feature = null;
        /**
         * The last point of the lineString.
         */
        private var _lastPoint:PointGeometry = null;

        /**
         * To know if we create a new feature, or if some points are already added
         */
        private var _newFeature:Boolean = true;

        /**
         * The start point of the temporary line
         */
        private var _startPoint:Pixel = new Pixel();

        private var pointDown:PointGeometry;

        private var pointUp:PointGeometry;

        /**
         * Handler which manage the doubleClick, to finalize the lineString
         */
        private var _dblClickHandler:ClickHandler = null;
        //标记是否为线，当为两个点时才加入
        private var count:int = 0;

        /**
         * @param map 地图对象引用
         * @param handlername handler名字，需保证唯一性
         * */
        public function DrawLineHandler(map:Map, handlername:String) {
            this._dblClickHandler = new ClickHandler(map, HandlerEnum.CLICK_HANDLER)
            super(map, handlername);
        }

        override protected function registerListeners():void {
            map.operateMode = MapActionEnum.MAP_DRAW;
            this._dblClickHandler.active = true;
            this._dblClickHandler.doubleClick = this.mouseDblClick;
            if (this.map) {
                this.map.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
                this.map.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
                this.map.addEventListener(MapEvent.MOVE_END, this.updateZoom);
                this.map.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
                this.map.addEventListener(DrawEvent.DRAW_START_POINT, drawStartPoint);
                this.map.addEventListener(DrawEvent.DRAW_END_POINT, drawEndPoint);
                this.map.stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
            }
        }

        override protected function unregisterListeners():void {
            this._dblClickHandler.active = false;
            if (this.map) {
                this.map.removeEventListener(MouseEvent.CLICK, this.drawLine);
                this.map.removeEventListener(MapEvent.MOVE_END, this.updateZoom);
                this.map.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
                this.map.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
                this.map.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
                this.map.removeEventListener(DrawEvent.DRAW_START_POINT, drawStartPoint);
                this.map.removeEventListener(DrawEvent.DRAW_END_POINT, drawEndPoint);
                this.map.stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);

            }
            this.map.operateMode = MapActionEnum.MAP_PAN;
            _snapLayerIds = null;
            _snapLayers = null;
            newFeature = true;
            count = 0;
            drawLayer.graphics.clear();
            if (null != this.feature) {
                this.feature.isLocked = false;
            }
            dbclickEnabled = true;
        }

        private function mouseMoveHandler(event:MouseEvent):void {
            super.mouseMoveSnapHandler(event);

            //画动态线
            if (!newFeature) {
                drawTemporaryLine(event);
            }

        }

        //画线过程中监听esc键，回退到画的上一个点
        private function keyDownHandler(event:KeyboardEvent):void {
           if(Keyboard.ESCAPE){
			   this.map.dispatchEvent(new DrawEvent(DrawEvent.DRAW_LINE_FEATURE_END, null));
			   return;
		   }
			if (event.charCode == Keyboard.BACKSPACE) {
                if (null == polyline) { //直接按esc退出了
					this.map.dispatchEvent(new DrawEvent(DrawEvent.DRAW_LINE_FEATURE_END, null));
					return;
                }
                if (polyline.pointList.length < 1) {
                    return;
                }
                var lastPoint:PointGeometry = polyline.pointList.getItemAt(polyline.pointList.length - 1) as PointGeometry;
                polyline.removePointByIndex();

                if (null != this.feature) {
                    this.feature.executeDrawing();
                    if (this.backToPreviouCallback != null) {
                        backToPreviouCallback(this.feature, lastPoint);
                    }
                }
                if (polyline.pointList.length == 0) {
                    if (count > 1) {
                        drawLayer.removeFeature(feature);
                    }
                    count = 0;
                    drawLayer.graphics.clear();
                    this.active = false;
                    if (!newFeature) {
                        newFeature = true;
                    }
                    //通知外界绘制完成
                    this.map.dispatchEvent(new DrawEvent(DrawEvent.DRAW_LINE_FEATURE_END, null));
                    this.map.stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);

                }
                else {
                    var point:PointGeometry = polyline.getLastPoint();
                    _startPoint = this.map.getLayerPxFromLocation(new Location(point.x, point.y));
                    drawTemporaryLine();
                }

            }
        }

        private function mouseDownHandler(event:MouseEvent):void {
            var pixel:Pixel = new Pixel(event.currentTarget.mouseX, event.currentTarget.mouseY);
            var lonlat:Location = this.map.getLocationFromLayerPx(pixel);

            pointDown = new PointGeometry(lonlat.lon, lonlat.lat);
        }

        private function mouseUpHandler(event:MouseEvent):void {
            var pixel:Pixel = new Pixel(event.currentTarget.mouseX, event.currentTarget.mouseY);
            var lonlat:Location = this.map.getLocationFromLayerPx(pixel);

            pointUp = new PointGeometry(lonlat.lon, lonlat.lat);
            if (!pointUp.equals(pointDown)) {
                //是拖动不画
            }
            else {
                //drawLine();
                beforeDrawLine(event);
            }
        }

        /**
         * 双节完成绘制事件
         * */
        public function mouseDblClick(Lastpx:Pixel, ... rest):void {
            if (dbclickEnabled) {
                this.drawFinalPath();
            }
        }

        /**
         * 画最后一个点
         */
        public function drawFinalPath():void {
            if (!newFeature) {
                newFeature = true;
                drawLayer.graphics.clear();

                this.map.stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);

                if (this.feature != null) {
                    //判断如果此条线只有一个点，则不删除。删除是为了双击结束处理,默认情况下双击结束，最后一个点删除

                    if (polyline.pointList.length > 2) {
                        polyline.removePointByIndex();
                    }
                    this.feature.geoStyle = drawLayer.geoStyle;
                    this.feature.executeDrawing();
                    // 标记结束绘制
                    this.feature.isLocked = false;
                    // drawLayer.redraw();
                    //抛出绘制完成事件
                    this.map.dispatchEvent(new DrawEvent(DrawEvent.DRAW_LINE_FEATURE_END, this.feature));
                    count = 0;

                }
            }
        }

        /**
         * 画起始点，由外部点击起始点通知开始画，不需要再鼠标按下开始画
         * */
        override protected function drawStartPoint(evt:DrawEvent):void {
            if (evt.newPoint != null) {
                drawLine(new PointGeometry(evt.newPoint.x, evt.newPoint.y));
            }
            else {
                return;
            }

        }

        /**
         * 画终止点，直接将最后的点传入，结束绘制
         * */
        override protected function drawEndPoint(evt:DrawEvent):void {
            if (evt.newPoint != null) {
                drawLine(new PointGeometry(evt.newPoint.x, evt.newPoint.y));
                if (!newFeature) {
                    newFeature = true;
                    drawLayer.graphics.clear();
                    this.map.stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
                    if (this.feature != null) {
                        this.feature.geoStyle = drawLayer.geoStyle;
                        /**
                         * 标记
                         * */
                        this.feature.isLocked = false;
                        this.feature.executeDrawing();
//                        this.map.dispatchEvent(new DrawEvent(DrawEvent.DRAW_FEATURE_END, this.feature));
                        this.map.dispatchEvent(new DrawEvent(DrawEvent.DRAW_LINE_FEATURE_END, this.feature));
                        count = 0;
                    }
                }
            }
            else {
                return;
            }
        }

        protected function beforeDrawLine(event:MouseEvent = null):void {
            var pixel:Pixel = new Pixel(drawLayer.mouseX, drawLayer.mouseY);
            var lonlat:Location = this.map.getLocationFromLayerPx(pixel);
            var point:PointGeometry = new PointGeometry(lonlat.lon, lonlat.lat);
            drawLine(point);
        }

        //画线
        protected function drawLine(newPoint:PointGeometry = null):void {
            count++;
            var style:IStyle = drawLayer.geoStyle;
            var point:PointGeometry = newPoint;

            if (snapReturn != null) {
                point = new PointGeometry(snapReturn.snapPoint.x, snapReturn.snapPoint.y);
//                if (this.snapClickCallback != null) {
//                    this.snapClickCallback(snapReturn.snapFeature, point);
//                }
//                snapReturn = null;
            }
            _startPoint = this.map.getLayerPxFromLocation(new Location(point.x, point.y));
            if (newFeature) {
                polyline = new PolylineGeometry();
                lastPoint = point;
                polyline.pointList.addItem(point);
//                trace("第" + count + "次" + ":" + drawLayer.mouseX + "  " + drawLayer.mouseY);
                newFeature = false;

                //抛出新增点事件
                this.map.dispatchEvent(new DrawEvent(DrawEvent.DRAW_NEW_POINT, this.feature, new Location(point.x, point.y)));
            }
            else {
                if (count == 2) {
                    // polyline.pointList.addItem(point);
                    this.feature = new Feature(polyline, null, style, null);
                    this.feature.name = "path." + id.toString();
                    this.feature.isLocked = true;
                    this.feature.labelVisible = false;
                    ++id;
                    drawLayer.addFeature(feature);
                }
                //解决：双击结束画线时mousedown相应两次，避免重复点加入
                if (!point.equals(lastPoint)) {
                    polyline.addPoint(point);
//                    trace("第" + count + "次" + ":" + drawLayer.mouseX + "  " + drawLayer.mouseY);
                    //count++;
                    //drawLayer.redraw();
                    this.feature.executeDrawing();
                    lastPoint = point;
                    //抛出新增点事件

                    this.map.dispatchEvent(new DrawEvent(DrawEvent.DRAW_NEW_POINT, this.feature, new Location(point.x, point.y)));
                }
            }
            if (snapReturn != null) {
                if (this.snapClickCallback != null) {
                   // this.snapClickCallback(snapReturn.snapFeature, point);
					//捕捉全部改为捕捉多个设施
					this.snapClickCallback(snapReturn.snapFeatures, point);
                }
                snapReturn = null;
            }
        }

        /**
         * 动态线
         */
        public function drawTemporaryLine(evt:MouseEvent = null):void {
            drawLayer.graphics.clear();
            drawLayer.graphics.lineStyle(2, 0x00ff00);
            drawLayer.graphics.moveTo(_startPoint.x, _startPoint.y);
            drawLayer.graphics.lineTo(drawLayer.mouseX, drawLayer.mouseY);
            drawLayer.graphics.endFill();

            //抛出画线过程中鼠标移动事件
            var pixel:Pixel = new Pixel(drawLayer.mouseX, drawLayer.mouseY);
            var lonlat:Location = this.map.getLocationFromLayerPx(pixel);
            this.map.dispatchEvent(new DrawEvent(DrawEvent.DRAW_POINT_MOUSEMOVING, this.feature, lonlat));

        }

        /**
         * @inherited
         * */
        override public function set map(value:Map):void {
            super.map = value;
            this._dblClickHandler.map = value;
        }

        private function updateZoom(evt:MapEvent):void {

            if (evt.zoomChanged) {
                drawLayer.graphics.clear();
                //we update the pixel of the last point which has changed
                if (polyline) {
                    var tempPoint:PointGeometry = polyline.getLastPoint();
                    _startPoint = this.map.getMapPxFromLocation(new Location(tempPoint.x, tempPoint.y));
                    drawTemporaryLine();
                }
            }
        }

        //Getters and Setters
        public function get id():Number {
            return _id;
        }

        public function set id(nb:Number):void {
            _id = nb;
        }

        public function get newFeature():Boolean {
            return _newFeature;
        }

        public function set newFeature(newFeature:Boolean):void {
            if (newFeature == true) {
                lastPoint = null;
            }
            _newFeature = newFeature;
        }

        public function get lastPoint():PointGeometry {
            return _lastPoint;
        }

        public function set lastPoint(value:PointGeometry):void {
            _lastPoint = value;
        }

        public function get startPoint():Pixel {
            return _startPoint;
        }

        public function set startPoint(pix:Pixel):void {
            _startPoint = pix;
        }
    }
}